package com.pvdnc.nsocket.protocol;

import com.pvdnc.nsocket.log.SLog;
import com.pvdnc.nsocket.protocol.base.Packet;

import java.util.concurrent.atomic.AtomicReference;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;


public class Splitter extends LengthFieldBasedFrameDecoder {
    private static final SLog LOG=new SLog(Splitter.class);

    private static final AtomicReference<Splitter> sInstance=new AtomicReference<>();

    public static Splitter getInstance(){
        if(sInstance.get()==null)
            sInstance.set(new Splitter());
        return sInstance.get();
    }

    public Splitter(){
        this(Packet.MAGIC);
    }

    private int mMagic;
    public Splitter(int magic) {
        super(Integer.MAX_VALUE, PacketCodec.FIXED_DATA_OFFSET, 4);

        mMagic=magic;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        LOG.d("splitter channel on active");
        super.channelActive(ctx);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        if(in.readableBytes()< Packet.MAGIC_LENGTH){//消息过短
            onInValidClient(ctx);
            return null;
        }
        //int magic=in.readInt();
        int magic=in.getInt(in.readerIndex());//不改变偏移
        //LOG.d("raw bytes:\n\t"+Arrays.toString(in.array()));
        LOG.d("magic:"+magic);//81 for demo
        if(magic!=mMagic) {//判断是否为本协议消息
            onInValidClient(ctx);
            return null;
        }
        return super.decode(ctx, in);
    }

    private void onInValidClient(ChannelHandlerContext ctx){
        Channel channel=ctx.channel();
        LOG.e("unexpected client connection from:"
                +channel.remoteAddress());
        channel.close();
    }
}
